package com.darren.euc.service.impl;

import com.darren.euc.entity.*;
import com.darren.euc.repository.TemporaryOrderRepository;
import com.darren.euc.service.ClientService;
import com.darren.euc.service.SpaceService;
import com.darren.euc.service.TemporaryOrderService;
import com.darren.euc.util.MyBeanUtils;
import com.darren.euc.util.StringUtil;
import net.sf.json.JSONObject;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Machenike-Pc on 2018/4/3.
 */

@Service
public class TemporaryOrderServiceImpl implements TemporaryOrderService {
    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    @Autowired
    private TemporaryOrderRepository temporaryOrderRepository;
    @Autowired
    private ClientService clientService;
    @Autowired
    private SpaceService spaceService;
    @Override
    public PageBean queryForPageUseHQL(JSONObject data, Integer pageSize, int currentPage) {
        String startTime;
        String endTime;
        Integer spaceId;
        String clientName;
        try{
            startTime = data.getString("startTime");
            Date x = new DateTime(startTime).toDate();
        }catch(Exception e){
            e.printStackTrace();
            startTime = null;
        }
        try {
            endTime = data.getString("endTime");
            Date x = new DateTime(endTime).toDate();
        }catch(Exception e){
            e.printStackTrace();
            endTime = null;
        }
        try{
            spaceId = data.getInt("spaceId");
        }catch(Exception e){
            e.printStackTrace();
            spaceId = 0;
        }
        try{
            clientName = data.getString("clientName");
        }catch(Exception e){
            e.printStackTrace();
            clientName = null;
        }
        String finalStartTime = startTime;
        String finalEndTime = endTime;
        Integer finalSpaceId = spaceId;
        String finalClientName = clientName;
        Specification<TemporaryOrder> querys = new Specification<TemporaryOrder>(){

            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(!StringUtil.isEmpty(finalStartTime)){
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("validTime"),  finalStartTime));
                }
                if(!StringUtil.isEmpty(finalEndTime)){
                    predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("validTime"), finalEndTime));
                }
                if(finalSpaceId > 0){
                    predicates.add(criteriaBuilder.equal(root.get("spaceId"),finalSpaceId));
                }
                if(!StringUtils.isEmpty(finalClientName)){
                    List<Clue> clus =clientService.queryCluesByClientName(finalClientName);
                    List<Integer> clientIds;
                    clientIds = clus.stream().map(Clue::getClient).map(item->item.getId()).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(clientIds)){
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get("clientId"));
                        for (Integer i:clientIds ) {
                            in.value(i);
                        }
                        predicates.add(in);
                    }
                }

                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        Sort sort = new Sort(Sort.Direction.DESC,"id");
         PageRequest pageRequest = new PageRequest(currentPage-1,pageSize,sort);

        Page<TemporaryOrder> orders =  temporaryOrderRepository.findAll(querys,pageRequest);

        PageBean pageBean = new PageBean();
        pageBean.setList(this.setSpaceNameAndClientName(orders.getContent()));
        pageBean.setTotalPage(orders.getTotalPages());
        long totalElements = orders.getTotalElements();
        pageBean.setTotalRow(Long.valueOf(totalElements).intValue());
        pageBean.setCurrentPage(currentPage);
        pageBean.setPageSize(pageSize);
        pageBean.init();
        return pageBean;

    }

    @Override
    public TemporaryOrder saveTempOrder(TemporaryOrder order) throws Exception {
        if(order.getId()!=null){
            return edit(order);
        }
        return add(order);
    }
    
    
    @Override
    public Integer getCurrentDayCount(Integer orderId) {
        return temporaryOrderRepository.findCountById(orderId);
    }

    private TemporaryOrder add(TemporaryOrder order) throws Exception{
        List<Clue> clus =clientService.queryCluesByClientNameEqual(order.getClientName());
        if(CollectionUtils.isEmpty(clus)){
            throw new Exception("用户不存在");
        }
        order.setClientId(clus.get(0).getClient().getId());
        order.setCreateTime(new Date());
        order.setLastModifyTime(new Date());
        order.setOrderStatus(0);//默认没有回款
        order.setOrderNumber(generateOrderNumber(order.getClientId()));
        order.setSpaceId(this.getSpaceIdByClientId(order.getClientId()));
        return temporaryOrderRepository.save(order);
    }

    private int getSpaceIdByClientId(int clientId) {
        Clue clue = clientService.findByClientId(clientId);
        if(clue != null){
            return clue.getSpaceId();
        }
         return 0;
    }

    private String generateOrderNumber(Integer clientId){
        Date currentTime = new Date();
        return "TP" + FORMATTER.format(currentTime) + (clientId%10);
    }

    private TemporaryOrder edit(TemporaryOrder order) {
        TemporaryOrder orderDB = findById(order.getId());
        if(orderDB != null){
            order.setId(orderDB.getId());
            //order.setOrderNumber(orderDB.getOrderNumber());
            order.setCreateTime(orderDB.getCreateTime());
            order.setSpaceId(orderDB.getSpaceId());
            order.setLastModifyTime(new Date());
            MyBeanUtils.copyPropertiesIgnoreNull(order,orderDB);
        }
        return temporaryOrderRepository.save(orderDB);
    }

    @Override
    public TemporaryOrder findById(Integer id) {
        TemporaryOrder order = temporaryOrderRepository.findOne(id);
        if(order!=null){
            order.setClientName(this.queryClient(order.getClientId()));
            order.setSpaceName(this.querySpaceById(order.getSpaceId()));
        }
        return order;
    }

    public List<TemporaryOrder> setSpaceNameAndClientName(List<TemporaryOrder> spaceNameAndClientName) {

        for (TemporaryOrder order:spaceNameAndClientName) {
            order.setClientName(this.queryClient(order.getClientId()));
            order.setSpaceName(this.querySpaceById(order.getSpaceId()));
        }
        return spaceNameAndClientName;
    }

    private String querySpaceById(int spaceId) {
        Space space = spaceService.findById(spaceId);
        if(space == null){
            return "unknown";
        }
        return space.getSpaceName();
    }

    private String queryClient(int clientId) {
        Clue client = clientService.findByClientId(clientId);
        if(client == null || client.getClient() == null)
            return "unknown";
        return client.getClient().getCompanyName();
    }
}
